//**************************************************************************
// Copyright 2008 Peter Project (http://www.codeplex.com/peter)
//
// License : GNU General Public License (GPL)
// For full text of the license please goto:
// http://www.gnu.org/licenses/gpl-2.0.html
//
// This code is provided on an AS IS basis, with no WARRANTIES,
// CONDITIONS or GUARANTEES of any kind.
//
//		File: PeterInterfaces.cs
//		Purpose: This file holds all the Interfaces for the Peter
//				 Plugin Architecture.
//
//**************************************************************************

using System;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;

namespace PeterInterface
{
	/// <summary>
	/// Plugin Type is either a Docking GUI, or User Defined
	/// </summary>
	public enum PeterPluginType
	{
		DockWindow,
		UserDefined
	};

	/// <summary>
	/// This class defines an attribute that needs to be added to all Peter Plugin classes...
	/// When creating a plugin you need to add the attribute - [PeterPlugin(PeterPluginType.DockWindow/*UserDefined*/)] - to your plugin class.
	/// When this plugin is loading, Peter will check for this attribute, and if it is not there, we will not load the plugin.
	/// </summary>
	[AttributeUsage(AttributeTargets.Class)]
	public sealed class PeterPluginAttribute : Attribute
	{
		/// <summary>
		/// Type of Plugin - UserDefined, or DockWindow.
		/// </summary>
		private PeterPluginType m_Type;

		/// <summary>
		/// Creates the plugin attribute, setting the type...
		/// </summary>
		/// <param name="type">Type of plugin.</param>
		public PeterPluginAttribute (PeterPluginType type)
		{
			this.m_Type = type;
		}

		/// <summary>
		/// Gets the Type of Plugin...
		/// </summary>
		public PeterPluginType Type
		{
			get { return this.m_Type; }
		}
	}

	/// <summary>
	/// If your plugin is going to be handled in a tab, then you need to implement this interface for that tab's control...
	/// Example...
	/// InternetBrowser Plugin implements the IPeterPlugin Interface
	///		ctrlInternetBrowser implements the IPeterPluginTab Interface, because it will show in Peter as a Tab.
	/// </summary>
	public interface IPeterPluginTab
	{
		/// <summary>
		/// Issues a Save command to the control...
		/// </summary>
		void Save ();

		/// <summary>
		/// Issues a Save As command to the control...
		/// </summary>
		/// <param name="filePath">New File Path.</param>
		void SaveAs (string filePath);

		/// <summary>
		/// Issues a Cut command to the control...
		/// </summary>
		void Cut ();

		/// <summary>
		/// Issues a Copy command to the control...
		/// </summary>
		void Copy ();

		/// <summary>
		/// Issues a Paste command to the control...
		/// </summary>
		void Paste ();

		/// <summary>
		/// Issues a Undo command to the control...
		/// </summary>
		void Undo ();

		/// <summary>
		/// Issues a Redo command to the control...
		/// </summary>
		void Redo ();

		/// <summary>
		/// Issues a Delete command to the control...
		/// </summary>
		void Delete ();

		/// <summary>
		/// Issues a Print command to the control...
		/// </summary>
		void Print ();

		/// <summary>
		/// Issues a Select All command to the control...
		/// </summary>
		void SelectAll ();

		/// <summary>
		/// Issues a Duplicate command to the control...
		/// </summary>
		void Duplicate ();

		/// <summary>
		/// Issues a Save command to the control...
		/// </summary>
		bool CloseTab ();

		/// <summary>
		/// Gets or Sets the Host application (Peter)...
		/// </summary>
		IPeterPluginHost Host { get; set; }

		/// <summary>
		/// Gets the file name of the control...
		/// </summary>
		string FileName { get; }

		/// <summary>
		/// Gets the Selected Text on the control...
		/// </summary>
		string Selection { get; }

		/// <summary>
		/// Gets if the control is able to Undo...
		/// </summary>
		bool AbleToUndo { get; }

		/// <summary>
		/// Gets if the control is able to Redo...
		/// </summary>
		bool AbleToRedo { get; }

		/// <summary>
		/// Gets if the control is able to Paste...
		/// </summary>
		bool AbleToPaste { get; }

		/// <summary>
		/// Gets if the control is able to Cut...
		/// </summary>
		bool AbleToCut { get; }

		/// <summary>
		/// Gets if the control is able to Copy...
		/// </summary>
		bool AbleToCopy { get; }

		/// <summary>
		/// Gets if the control is able to Select All...
		/// </summary>
		bool AbleToSelectAll { get; }

		/// <summary>
		/// Gets if the control is able to Save...
		/// </summary>
		bool AbleToSave { get; }

		/// <summary>
		/// Gets if the control is able to Delete...
		/// </summary>
		bool AbleToDelete { get; }

		/// <summary>
		/// Gets if the control needs to be saved (before closing)...
		/// </summary>
		bool NeedsSaving { get; }

		/// <summary>
		/// Gets or Sets the Text to appear on the controls tab...
		/// </summary>
		string TabText { get; set; }

		/// <summary>
		/// Marks all of the given regex...
		/// </summary>
		/// <param name="reg">Regex to look for.</param>
		void MarkAll (Regex reg);

		/// <summary>
		/// Finds the next occurance of the given regex...
		/// </summary>
		/// <param name="reg">Regex to look for.</param>
		/// <param name="searchUp">bool - should we search up?</param>
		/// <returns>Found or not.</returns>
		bool FindNext (Regex reg, bool searchUp);

		/// <summary>
		/// Replaces the next occurance of the given regex...
		/// </summary>
		/// <param name="reg">Regex to look for.</param>
		/// <param name="replaceWith">string to replace item with.</param>
		/// <param name="searchUp">bool - should we search up?</param>
		void ReplaceNext (Regex reg, string replaceWith, bool searchUp);

		/// <summary>
		/// Replaces all occurances of the given regex...
		/// </summary>
		/// <param name="reg">Regex to look for.</param>
		/// <param name="replaceWith">string to replace item with.</param>
		void ReplaceAll (Regex reg, string replaceWith);

		/// <summary>
		/// Selects a word at the given location...
		/// </summary>
		/// <param name="line">Line word is on.</param>
		/// <param name="offset">Offset word is at.</param>
		/// <param name="wordLeng">Length of word.</param>
		void SelectWord (int line, int offset, int wordLeng);
	}

	/// <summary>
	/// Interface for the Host Peter Application...
	/// </summary>
	public interface IPeterPluginHost
	{
		/// <summary>
		/// Gets the Type for a Editor in string format (typeof(Editor))...
		/// </summary>
		string EditorType { get; }

		/// <summary>
		/// Gets the path the Application started in...
		/// </summary>
		string ApplicationExeStartPath { get; }

		/// <summary>
		/// Creates a new blank editor...
		/// </summary>
		void NewDocument ();

		/// <summary>
		/// Writes the given text in the status bar...
		/// </summary>
		/// <param name="text">Text to Write.</param>
		void Trace (string text);

		/// <summary>
		/// Saves the Given Content As...
		/// </summary>
		/// <param name="tab">Content to Save</param>
		void SaveAs (IPeterPluginTab tab);

		/// <summary>
		/// Creates a new Editor with the given file...
		/// </summary>
        /// <param name="path">File to load in Editor.</param>
		/// <param name="tabName">Name of Tab.</param>
		void CreateEditor (string path, string tabName);

		/// <summary>
		/// Creates a new Editor with the given file...
		/// </summary>
        /// <param name="path">File to load in Editor.</param>
		/// <param name="tabName">Name of Tab.</param>
		/// <param name="image">Icon for Tab.</param>
		void CreateEditor (string path, string tabName, Icon image);

		/// <summary>
		/// Creates a new Editor with the given file...
		/// </summary>
        /// <param name="path">File to load in Editor.</param>
		/// <param name="tabName">Name of Tab.</param>
		/// <param name="image">Icon for Tab.</param>
		/// <param name="addToContent">Content to add to group.</param>
		void CreateEditor (string path, string tabName, Icon image, IDockContent addToContent);

		/// <summary>
		/// Gets the Shell Icon for the given file...
		/// </summary>
        /// <param name="path">Path to File.</param>
		/// <param name="linkOverlay">Link Overlay or not.</param>
		/// <returns>Shell Icon for File.</returns>
		Icon GetFileIcon (string path, bool linkOverlay);

		/// <summary>
		/// Adds the given Dock Content to the form...
		/// </summary>
		/// <param name="content">Content to Add.</param>
		void AddDockContent (DockContent content);

		/// <summary>
		/// Adds the given Dock Content to the form...
		/// </summary>
		/// <param name="content">Content to Add.</param>
		/// <param name="state">State of Content</param>
		void AddDockContent (DockContent content, DockState state);

		/// <summary>
		/// Adds the given Dock Content to the form...
		/// </summary>
		/// <param name="content">Content to Add.</param>
		/// <param name="floatingRec">Floating Rectangle</param>
		void AddDockContent (DockContent content, Rectangle floatingRec);
	}

	/// <summary>
	/// Interface for a Peter Plugin...
	/// </summary>
	public interface IPeterPlugin
	{
		/// <summary>
		/// This method is called when the plugin is loaded...
		/// </summary>
		void Start ();

		/// <summary>
		/// This method is called when Peter Closes...
		/// </summary>
		void Close ();

		/// <summary>
		/// This is the Name of the plugin...
		/// </summary>
		string Name { get; }

		/// <summary>
		/// Gets if the Plugin can load files or not...
		/// </summary>
		bool AbleToLoadFiles { get; }

		/// <summary>
		/// Loads the Given File...
		/// </summary>
		/// <param name="filePath">Path to file to load.</param>
		/// <returns>True if Loaded, otherwise false</returns>
		bool LoadFile (string filePath);

		/// <summary>
		/// Does this plugin have a menu item for the plugin menu...
		/// </summary>
		bool HasMenu { get; }

		/// <summary>
		/// Does this plugin have a menu item for the tab menu...
		/// </summary>
		bool HasTabMenu { get; }

		/// <summary>
		/// Does this plugin have a menu item for the context menu...
		/// </summary>
		bool HasContextMenu { get; }

		/// <summary>
		/// The Author of the Plugin...
		/// </summary>
		string Author { get; }

		/// <summary>
		/// The Version of the Plugin...
		/// </summary>
		string Version { get; }

		/// <summary>
		/// The Image for the Plugin...
		/// </summary>
		Image PluginImage { get; }

		/// <summary>
		/// Gets the Plugin Menu Item...
		/// </summary>
		/// <returns>Tool Strip Menu Item</returns>
		ToolStripMenuItem GetMenu ();

		/// <summary>
		/// Gets the Tab Menu Items...
		/// </summary>
		/// <returns>Tool Strip Menu Item Array</returns>
		ToolStripMenuItem[] GetTabMenu ();

		/// <summary>
		/// Gets the Context Menu Items...
		/// </summary>
		/// <returns>Tool Strip Menu Item Array</returns>
		ToolStripMenuItem[] GetContextMenu ();

		/// <summary>
		/// Gets the Type of the Plugin...
		/// </summary>
		PeterPluginType Type { get; }

		/// <summary>
		/// Gets or Sets the Host Appliction Interface...
		/// </summary>
		IPeterPluginHost Host { get; set; }

		/// <summary>
		/// Occurs when the Active Content has changed...
		/// </summary>
		/// <param name="tab">Active Content</param>
		void ActiveContentChanged (IDockContent tab);

		/// <summary>
		/// Checks the content string when loading Application...
		/// </summary>
		/// <param name="contentString">Content String</param>
		/// <returns>True if Match, other wise false</returns>
		bool CheckContentString (string contentString);

		/// <summary>
		/// Gets the Starting Content...
		/// </summary>
		/// <param name="contentString">Content String</param>
		/// <returns>The Newly created content</returns>
		IDockContent GetContent (string contentString);

		/// <summary>
		/// Gets the Option Panel to add to the Main Option Dialog...
		/// </summary>
		/// <returns>Option Panel Control.</returns>
		Control OptionPanel { get; }

		/// <summary>
		/// Occurs when the Apply button on the options dialog is pressed...
		/// </summary>
		void ApplyOptions ();
	}
}
